package com.inspur.edp.bef.bizentity;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityErrorCodeEnum;
import com.inspur.edp.bef.bizentity.exceptions.BusinessEntityException;
import com.inspur.edp.bef.bizentity.json.object.BizObjectDeserializer;
import com.inspur.edp.bef.bizentity.json.object.BizObjectSerializer;
import com.inspur.edp.bef.bizentity.operation.BizAction;
import com.inspur.edp.bef.bizentity.operation.BizOperation;
import com.inspur.edp.bef.bizentity.operation.collection.BizActionCollection;
import com.inspur.edp.bef.bizentity.operation.collection.DeterminationCollection;
import com.inspur.edp.bef.bizentity.operation.collection.TccSettingCollection;
import com.inspur.edp.bef.bizentity.operation.collection.ValidationCollection;
import com.inspur.edp.bef.bizentity.operation.internalbeaction.DeleteBEAction;
import com.inspur.edp.bef.bizentity.operation.internalbeaction.IInternalBEAction;
import com.inspur.edp.bef.bizentity.operation.internalbeaction.ModifyBEAction;
import com.inspur.edp.bef.bizentity.operation.internalbeaction.RetrieveBEAction;
import com.inspur.edp.bef.bizentity.operation.internalmgraction.TccSettingElement;
import com.inspur.edp.cef.designtime.api.IGspCommonField;
import com.inspur.edp.cef.designtime.api.collection.CommonDtmCollection;
import com.inspur.edp.cef.designtime.api.collection.CommonValCollection;
import com.inspur.edp.cef.designtime.api.element.GspAssociationKey;
import com.inspur.edp.cef.designtime.api.element.GspElementDataType;
import com.inspur.edp.cef.designtime.api.element.GspElementObjectType;
import com.inspur.edp.cef.designtime.api.operation.CommonDetermination;
import com.inspur.edp.cef.designtime.api.operation.CommonTriggerPointType;
import com.inspur.edp.cef.designtime.api.operation.CommonValidation;
import com.inspur.edp.cef.designtime.api.operation.ExecutingDataStatus;
import com.inspur.edp.cef.designtime.api.util.Guid;
import com.inspur.edp.das.commonmodel.IGspCommonElement;
import com.inspur.edp.das.commonmodel.IGspCommonObject;
import com.inspur.edp.das.commonmodel.collection.GspElementCollection;
import com.inspur.edp.das.commonmodel.collection.GspObjectCollection;
import com.inspur.edp.das.commonmodel.entity.GspCommonObject;
import com.inspur.edp.das.commonmodel.entity.element.GspCommonAssociation;
import com.inspur.edp.das.commonmodel.entity.object.GspColumnGenerate;
import com.inspur.edp.das.commonmodel.entity.object.GspCommonObjectType;
import lombok.Getter;
import lombok.Setter;

import java.util.EnumSet;

/**
 * 业务实体节点
 * 新建主节点
 * <blockquote><pre>
 * 	    public  GspBizEntityObject createNewMainObject() {
 *         GspBizEntityObject mainObj = new GspBizEntityObject();
 *         mainObj.setID(Guid.newGuid().toString());
 *         mainObj.setCode("mainObjCode");
 *         mainObj.setName("主对象");
 *         mainObj.setObjectType(GspCommonObjectType.MainObject);
 *         GspBizEntityElement idElement = initIDElement();
 *         GspColumnGenerate newColumnGenerate = new GspColumnGenerate();
 *         newColumnGenerate.setElementID(idElement.getID());
 *         newColumnGenerate.setGenerateType("Guid");
 *         mainObj.setColumnGenerateID(newColumnGenerate);
 *         mainObj.getContainElements().add(idElement);
 *         return mainObj;
 *     }
 *
 *     private GspBizEntityElement initIDElement() {
 *         GspBizEntityElement idElement = new GspBizEntityElement();
 *         idElement.setID(Guid.newGuid().toString());
 *         idElement.setCode("Code");
 *         idElement.setName("Name");
 *         idElement.setLabelID("ID");
 *         idElement.setMDataType(GspElementDataType.String);
 *         idElement.setObjectType(GspElementObjectType.None);
 *         idElement.setLength(36);
 *         idElement.setPrecision(0);
 *         idElement.setIsRequire(true);
 *         return idElement;
 *     }
 * </pre></blockquote>
 * 新建子对象：{@link #createChildObject}
 */
@JsonDeserialize(using = BizObjectDeserializer.class)
@JsonSerialize(using = BizObjectSerializer.class)
public class GspBizEntityObject extends GspCommonObject implements Cloneable {

    // region 私有属性
    private DeterminationCollection determinations;
    private CommonDtmCollection bizCommonDtms;
    private CommonValCollection bizCommonVals;
    private ValidationCollection validations;
    private BizActionCollection bizActions;

    private LogicDeleteControlInfo logicDeleteControlInfo;
    private TccSettingCollection tccSettings;
    private String securityElementID;

    // endregion

    // region 构造函数

    /**
     * 业务实体节点默认构造函数
     */
    public GspBizEntityObject() {
        super();
    }

    // endregion

    // region 公共属性

    /**
     * 获取当前节点是否根节点
     */
    public final boolean getIsRootNode() {
        return getParentObject() == null;
    }

    public LogicDeleteControlInfo getLogicDeleteControlInfo() {
        if (logicDeleteControlInfo == null) {
            logicDeleteControlInfo = new LogicDeleteControlInfo();
        }
        return logicDeleteControlInfo;
    }

    public void setLogicDeleteControlInfo(LogicDeleteControlInfo logicDeleteControlInfo) {
        this.logicDeleteControlInfo = logicDeleteControlInfo;
    }

    public final DeterminationCollection getDeterminations() {
        if (determinations == null) {
            determinations = new DeterminationCollection();

        }
        determinations.setOwner(this);
        return determinations;
    }

    /**
     * 获取当前对象上的联动计算集合
     */
    public final CommonDtmCollection getBizCommonDtms() {
        if (bizCommonDtms == null) {
            bizCommonDtms = new CommonDtmCollection();
        } else if (bizCommonDtms.size() > 0) {
            return bizCommonDtms;
        }
        if (this.getDtmBeforeRetrieve() != null && this.getDtmBeforeRetrieve().size() > 0) {
            bizCommonDtms.addAll(this.getDtmBeforeRetrieve());
        }

        if (this.getDtmAfterCreate() != null && this.getDtmAfterCreate().size() > 0) {
            bizCommonDtms.addAll(this.getDtmAfterCreate());
        }
        if (this.getDtmAfterLoading() != null && this.getDtmAfterLoading().size() > 0) {
            bizCommonDtms.addAll(this.getDtmAfterLoading());
        }
        if (this.getDtmBeforeQuery() != null && this.getDtmBeforeQuery().size() > 0) {
            bizCommonDtms.addAll(this.getDtmBeforeQuery());
        }
        if (this.getDtmAfterQuery() != null && this.getDtmAfterQuery().size() > 0) {
            bizCommonDtms.addAll(this.getDtmAfterQuery());
        }
        if (this.getDtmAfterModify() != null && this.getDtmAfterModify().size() > 0) {
            bizCommonDtms.addAll(this.getDtmAfterModify());
        }
        if (this.getDtmBeforeSave() != null && this.getDtmBeforeSave().size() > 0) {
            bizCommonDtms.addAll(this.getDtmBeforeSave());
        }
        if (this.getDtmCancel() != null && this.getDtmCancel().size() > 0) {
            bizCommonDtms.addAll(this.getDtmCancel());
        }
        if (this.getItemDeletingDtms() != null && this.getItemDeletingDtms().size() > 0) {
            bizCommonDtms.addAll(this.getItemDeletingDtms());
        }

        //获取字段上的联动计算和计算规则
        for (IGspCommonField commonField : getContainElements()) {
            if (commonField instanceof GspBizEntityElement) {
                GspBizEntityElement gspBizEntityElement = (GspBizEntityElement) commonField;
                CommonDtmCollection valueChangeDtms = gspBizEntityElement.getValueChangedDtms();
                if (valueChangeDtms != null && valueChangeDtms.size() > 0) {
                    bizCommonDtms.addAll(valueChangeDtms);
                }

                CommonDtmCollection computationDtms = gspBizEntityElement.getComputationDtms();
                if (computationDtms != null && computationDtms.size() > 0) {
                    bizCommonDtms.addAll(computationDtms);
                }
            }
        }
        return bizCommonDtms;
    }

    /**
     * 获取当前对象上的计算规则
     */
    public final CommonValCollection getBizCommonVals() {
        if (bizCommonVals == null) {
            bizCommonVals = new CommonValCollection();
        } else if (bizCommonVals.size() > 0) {
            return bizCommonVals;
        }

        if (this.getValAfterModify() != null && this.getValAfterModify().size() > 0) {
            for (CommonValidation commonValidation : this.getValAfterModify()) {
                CommonValidation exist = bizCommonVals.stream().filter(item -> item.getID().equals(commonValidation.getID())).findFirst().orElse(null);
                if (exist == null) {
                    bizCommonVals.add(commonValidation);
                }
            }
        }
        if (this.getallValBeforeSave() != null && this.getallValBeforeSave().size() > 0) {
            for (CommonValidation commonValidation : this.getallValBeforeSave()) {
                CommonValidation exist = bizCommonVals.stream().filter(item -> item.getID().equals(commonValidation.getID())).findFirst().orElse(null);
                if (exist == null) {
                    bizCommonVals.add(commonValidation);
                }
            }
        }
        if (this.getValAfterSave() != null && this.getValAfterSave().size() > 0) {
            for (CommonValidation commonValidation : this.getValAfterSave()) {
                CommonValidation exist = bizCommonVals.stream().filter(item -> item.getID().equals(commonValidation.getID())).findFirst().orElse(null);
                if (exist == null) {
                    bizCommonVals.add(commonValidation);
                }
            }
        }
        if (this.getItemDeletingVals() != null && this.getItemDeletingVals().size() > 0) {
            for (CommonValidation commonValidation : this.getItemDeletingVals()) {
                CommonValidation exist = bizCommonVals.stream().filter(item -> item.getID().equals(commonValidation.getID())).findFirst().orElse(null);
                if (exist == null) {
                    bizCommonVals.add(commonValidation);
                }
            }
        }
        return bizCommonVals;
    }

    public final void setDeterminations(DeterminationCollection value) {
        determinations = value;
        for (BizOperation validation : value) {
            validation.setOwner(this);
        }
        if (determinations != null) {
            determinations.setOwner(this);
        }
    }

    public final ValidationCollection getValidations() {
        if (validations == null) {
            validations = new ValidationCollection();
        }
        validations.setOwner(this);
        return validations;
    }

    public final void setValidations(ValidationCollection value) {
        validations = value;
        for (BizOperation validation : value) {
            validation.setOwner(this);
        }
        validations.setOwner(this);
    }

    @Getter
    @Setter
    private CommonDtmCollection itemDeletingDtms;

    @Getter
    @Setter
    private CommonValCollection itemDeletingVals;

    public final BizActionCollection getBizActions() {
        if (bizActions == null) {
            bizActions = new BizActionCollection();
        }
        bizActions.setOwner(this);
        return bizActions;
    }

    public final void setBizActions(BizActionCollection value) {
        bizActions = value;
        for (BizOperation validation : value) {
            validation.setOwner(this);
        }
        bizActions.setOwner(this);
    }

    public final void setTccSettings(TccSettingCollection value) {
        tccSettings = value;
        for (TccSettingElement settingElement : tccSettings) {
            settingElement.setOwner(this);
            settingElement.getTccAction().setOwner(this);
        }
        tccSettings.setOwner(this);
    }

    public final TccSettingCollection getTccSettings() {
        if (tccSettings == null) {
            tccSettings = new TccSettingCollection();
        }
        tccSettings.setOwner(this);
        return tccSettings;
    }

    public String getSecurityElementID() {
        return securityElementID;
    }

    public void setSecurityElementID(String securityElementID) {
        this.securityElementID = securityElementID;
    }

    /**
     * 当前节点的所属模型
     */
    public final GspBusinessEntity getBelongModel() {
        return (GspBusinessEntity) super.getBelongModel();
    }

    /**
     * 父节点
     */
    public final GspBizEntityObject getParentObject() {
        return (GspBizEntityObject) ((super.getParentObject() instanceof GspBizEntityObject) ? super.getParentObject()
                : null);
    }

    public final void setParentObject(GspBizEntityObject value) {
        super.setParentObject(value);
    }

    // region CommonDataType

    /**
     * 获取保存前事件联动计算集合
     */
    @Override
    public CommonDtmCollection getAllDtmBeforeSave() {
        CommonDtmCollection dtmAllBeforeSave = new CommonDtmCollection();
        CommonDtmCollection dtmBeforeSave = getDtmBeforeSave();
        if (dtmBeforeSave != null && dtmBeforeSave.size() > 0) {
            dtmAllBeforeSave.addAll(dtmBeforeSave);
        }

        CommonDtmCollection dtmDel = getItemDeletingDtms();
        if (dtmDel != null && dtmDel.size() > 0) {
            for (CommonDetermination commonDetermination : dtmDel) {
                if (isNoneDataStatus(commonDetermination.getGetExecutingDataStatus())) {
                    commonDetermination.setGetExecutingDataStatus(EnumSet.of(ExecutingDataStatus.Deleted));
                }
                if (commonDetermination.getTriggerPointType() == CommonTriggerPointType.BeforeSave) ;
                dtmAllBeforeSave.add(commonDetermination);
            }
        }
        //获取字段上的联动计算和计算规则
        for (IGspCommonField commonField : getContainElements()) {
            if (commonField instanceof GspBizEntityElement) {
                GspBizEntityElement gspBizEntityElement = (GspBizEntityElement) commonField;
                CommonDtmCollection valueChangeDtms = gspBizEntityElement.getValueChangedDtms();
                if (valueChangeDtms != null && valueChangeDtms.size() > 0) {
                    for (CommonDetermination valueDtm : valueChangeDtms) {
                        if (!valueDtm.getRequestElements().contains(commonField.getID())) {
                            valueDtm.getRequestElements().add(commonField.getID());
                        }
                    }
                    dtmAllBeforeSave.addAll(valueChangeDtms);
                }

                CommonDtmCollection computationDtms = gspBizEntityElement.getComputationDtms();
                if (computationDtms != null && computationDtms.size() > 0) {
                    for (CommonDetermination computationDtm : computationDtms) {
                        if (!computationDtm.getRequestElements().contains(commonField.getID())) {
                            computationDtm.getRequestElements().add(commonField.getID());
                        }
                    }
                    dtmAllBeforeSave.addAll(computationDtms);
                }
            }
        }
        return dtmAllBeforeSave;
    }

    /**
     * 包含原来的修改后，以及删除的修改后
     * <p>字段的是：保存前  create update
     */
    @Override
    public CommonDtmCollection getAllDtmAfterModify() {
        CommonDtmCollection dtmAllAfterModify = new CommonDtmCollection();
        CommonDtmCollection dtmAfterModify = getDtmAfterModify();
        if (dtmAfterModify != null && dtmAfterModify.size() > 0) {
            dtmAllAfterModify.addAll(dtmAfterModify);
        }
        CommonDtmCollection dtmDel = getItemDeletingDtms();
        if (dtmDel != null && dtmDel.size() > 0) {
            for (CommonDetermination commonDetermination : dtmDel) {
                if (isNoneDataStatus(commonDetermination.getGetExecutingDataStatus())) {
                    commonDetermination.setGetExecutingDataStatus(EnumSet.of(ExecutingDataStatus.Deleted));
                }
                if (commonDetermination.getTriggerPointType() == CommonTriggerPointType.AfterModify)
                    dtmAllAfterModify.add(commonDetermination);
            }
        }
        return dtmAllAfterModify;
    }

    /**
     * [查询前]联动计算, 用来自定义过滤条件
     */
    private CommonDtmCollection dtmBeforeQuery = new CommonDtmCollection();

    public CommonDtmCollection getDtmBeforeQuery() {
        return dtmBeforeQuery;
    }

    public void setDtmBeforeQuery(CommonDtmCollection value) {
        setDtms(dtmBeforeQuery, value);
    }

    public CommonDtmCollection getDtmCancel() {
        return dtmCancel;
    }

    public void setDtmCancel(CommonDtmCollection value) {
        setDtms(dtmCancel, value);
    }

    private CommonDtmCollection dtmCancel = new CommonDtmCollection();

    /**
     * [查询前]联动计算, 用来自定义过滤条件
     */
    private CommonDtmCollection dtmAfterQuery = new CommonDtmCollection();

    public CommonDtmCollection getDtmAfterQuery() {
        return dtmAfterQuery;
    }

    public void setDtmAfterQuery(CommonDtmCollection value) {
        setDtms(dtmAfterQuery, value);
    }

    private CommonValCollection allValBeforeSave = new CommonValCollection();

    @Override
    public CommonValCollection getallValBeforeSave() {
        if (allValBeforeSave == null) {
            allValBeforeSave = new CommonValCollection();
        } else if (allValBeforeSave.size() > 0) {
            return allValBeforeSave;
        }
        CommonValCollection valBeforeSave = getValBeforeSave();
        if (valBeforeSave != null && valBeforeSave.size() > 0) {
            allValBeforeSave.addAll(valBeforeSave);
        }
        CommonValCollection valDels = getItemDeletingVals();
        if (valDels != null && valDels.size() > 0) {
            for (CommonValidation commonValidation : valDels) {
                if (isNoneDataStatus(commonValidation.getGetExecutingDataStatus())) {
                    commonValidation.setGetExecutingDataStatus(EnumSet.of(ExecutingDataStatus.Deleted));
                }
                if (commonValidation.getTriggerPointType() == CommonTriggerPointType.BeforeSave)
                    allValBeforeSave.add(commonValidation);
            }
        }
        //获取字段上的联动计算和计算规则
        for (IGspCommonField commonField : getContainElements()) {
            if (commonField instanceof GspBizEntityElement) {
                GspBizEntityElement gspBizEntityElement = (GspBizEntityElement) commonField;
                CommonValCollection changedVals = gspBizEntityElement.getValueChangedVals();
                if (changedVals != null && changedVals.size() > 0) {
                    for (CommonValidation val : changedVals) {
                        if (!val.getRequestElements().contains(gspBizEntityElement.getID())) {
                            val.getRequestElements().add(gspBizEntityElement.getID());
                        }
                    }
                    allValBeforeSave.addAll(changedVals);
                }
            }
        }
        return allValBeforeSave;
    }

    private static boolean isNoneDataStatus(EnumSet<ExecutingDataStatus> set) {
        return set == null || set.isEmpty() || set.stream().allMatch(item -> item == ExecutingDataStatus.None);
    }

    /**
     * [查询前]联动计算, 用来自定义过滤条件
     */
    private CommonDtmCollection dtmBeforeRetrieve = new CommonDtmCollection();

    public CommonDtmCollection getDtmBeforeRetrieve() {
        return dtmBeforeRetrieve;
    }

    public void setDtmBeforeRetrieve(CommonDtmCollection value) {
        setDtms(dtmBeforeRetrieve, value);
    }

    private CommonDtmCollection dtmAfterLoading = new CommonDtmCollection();

    public CommonDtmCollection getDtmAfterLoading() {
        return dtmAfterLoading;
    }

    public void setDtmAfterLoading(CommonDtmCollection value) {
        setDtms(dtmAfterLoading, value);
    }

    private CommonValCollection valAfterSave = new CommonValCollection();

    /**
     * [保存后]校验规则
     */
    public CommonValCollection getValAfterSave() {
        return valAfterSave;
    }

    @Override
    public CommonValCollection getAllValAfterModify() {
        CommonValCollection rez = new CommonValCollection();
        CommonValCollection valAfterModify = getValAfterModify();
        if (valAfterModify != null) {
            rez.addAll(valAfterModify);
        }
        CommonValCollection valDels = getItemDeletingVals();
        if (valDels != null && valDels.size() > 0) {
            for (CommonValidation commonValidation : valDels) {
                if (isNoneDataStatus(commonValidation.getGetExecutingDataStatus())) {
                    commonValidation.setGetExecutingDataStatus(EnumSet.of(ExecutingDataStatus.Deleted));
                }
                if (commonValidation.getTriggerPointType() == CommonTriggerPointType.AfterModify)
                    rez.add(commonValidation);
            }
        }
        return rez;
    }

    public void setValAfterSave(CommonValCollection value) {
        valAfterSave = value;
    }

    // endregion

    // endregion

    // region 方法

    /**
     * 克隆
     *
     * @return 返回一个全新的节点对象
     */
    @Override
    public GspBizEntityObject clone() {
        GspCommonObject tempVar = super.clone();
        GspBizEntityObject node = (GspBizEntityObject) ((tempVar instanceof GspBizEntityObject) ? tempVar : null);
        if (node == null) {
            return null;
        }
        if (getDeterminations() != null) {
            DeterminationCollection tempVar2 = getDeterminations().clone();
            node.setDeterminations(
                    (DeterminationCollection) ((tempVar2 instanceof DeterminationCollection) ? tempVar2 : null));
        }
        if (getValidations() != null) {
            ValidationCollection tempVar3 = validations.clone();
            node.setValidations((ValidationCollection) ((tempVar3 instanceof ValidationCollection) ? tempVar3 : null));
        }
        if (getBizActions() != null) {
            BizActionCollection tempVar4 = bizActions.clone();
            node.setBizActions((BizActionCollection) ((tempVar4 instanceof BizActionCollection) ? tempVar4 : null));
        }
        return node;
    }

    /**
     * 创建属性
     */
    @Override
    protected GspBizEntityElement createElement() {
        return new GspBizEntityElement();
    }

    // region 依赖实体
    public final void mergeWithDependentObject(GspBizEntityObject dependentObject, boolean isInit) {
        if (!getIsRef()) {
            return;
        }
        // 基本信息
        mergeObjectBaseInfo(dependentObject, isInit);

        // 字段操作
        mergeContainElements(dependentObject);
        mergeContainAction(dependentObject);
        mergeContainDeterminations(dependentObject);
        mergeContainValidation(dependentObject);

        // 子对象
        mergeChildObjects(dependentObject, isInit);
    }

    private void mergeObjectBaseInfo(GspBizEntityObject dependentObject, boolean isInit) {
        // 当且仅当首次dbe带出时，带出对象的编号名称；后续不覆盖
        if (isInit) {
            setCode(dependentObject.getCode());
            setName(dependentObject.getName());
        }

        setOrderbyCondition(dependentObject.getOrderbyCondition());
        setFilterCondition(dependentObject.getFilterCondition());
        setIsReadOnly(dependentObject.getIsReadOnly());
        setObjectType(dependentObject.getObjectType());
        setIsVirtual(dependentObject.getIsVirtual());
        setBelongModelID(dependentObject.getBelongModelID());

        // 处理ID字段
        IGspCommonElement idElement = getContainElements().getItem(getColumnGenerateID().getElementID());
        getContainElements().removeItem(idElement);

        setColumnGenerateID(dependentObject.getColumnGenerateID());
        setContainConstraints(dependentObject.getContainConstraints());
        for (GspAssociationKey key : dependentObject.getKeys()) {
            getKeys().add(((GspAssociationKey) ((key instanceof GspAssociationKey) ? key : null)).clone());
        }
    }

    private void mergeContainElements(GspBizEntityObject dependentObject) {
        if (getContainElements() == null) {
            setContainElements(new GspElementCollection(this));
        }

        GspCommonAssociation parentAsso = null;
        if (getContainElements().size() > 0) {
            parentAsso = (GspCommonAssociation) getContainElements().get(0).getParentAssociation();
        }
        GspElementCollection elements = getContainElements().clone(this, parentAsso);
        GspElementCollection dbeElements = dependentObject.getContainElements();

        // 清空
        getContainElements().clear();

        // 添加当前be的字段,若为dbe字段，则删除重加所属对象改为当前对象
        for (IGspCommonField e : elements) {
            GspBizEntityElement ele = (GspBizEntityElement) e;
            if (ele.getIsRef()) {
                GspBizEntityElement dependentEle = (GspBizEntityElement) dbeElements.getItem(ele.getID());
                addDbeElement(dependentEle, (IGspCommonElement) ele);
                dbeElements.removeItem(dependentEle);
            } else {
                getContainElements().add(ele);
            }
        }

        // 添加dbe新增的ele
        if (dbeElements == null || dbeElements.size() < 1) {
            return;
        }
        for (IGspCommonField ele : dbeElements) {
            addDbeElement((IGspCommonElement) ((ele instanceof IGspCommonElement) ? ele : null), null);
        }
    }

    private void addDbeElement(IGspCommonElement ele, IGspCommonElement orgEle) {
        if (ele == null) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_COMMON_0003, "IGspCommonElement");
        }
        if (!(ele instanceof GspBizEntityElement)) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0006, "GspBizEntityElement");
        }
        GspBizEntityElement dbeEle = (GspBizEntityElement) ele;
        GspBizEntityElement newEle = (GspBizEntityElement) dbeEle.clone(this, dbeEle.getParentAssociation());
        if (!(newEle instanceof GspBizEntityElement)) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_CLONE_0001, "GspBizEntityElement");
        }

        newEle.setID(dbeEle.getID());
        newEle.setIsRef(true);
        if (newEle.getChildElements() != null) {
            for (IGspCommonField childEle : newEle.getChildElements()) {
                childEle.setIsRef(true);
            }
        }
        if (orgEle != null) {
            newEle.setColumnID(orgEle.getColumnID());
            if (newEle.getChildElements() != null) {
                for (int i = 0; i < newEle.getChildElements().size(); i++) {
                    IGspCommonElement commonEl = (IGspCommonElement) newEle.getChildElements().get(i);
                    if (commonEl == null) {
                        continue;
                    }
                    if (i >= orgEle.getChildElements().size()) {
                        continue;
                    }
                    commonEl.setColumnID(((IGspCommonElement) orgEle.getChildElements().get(i)).getColumnID());
                }
            }
        }

        getContainElements().add(newEle);
    }

    private void mergeContainDeterminations(GspBizEntityObject dependentObject) {
        getDeterminations().mergeDbeOperations(dependentObject.getDeterminations());
    }

    private void mergeContainValidation(GspBizEntityObject dependentObject) {
        getValidations().mergeDbeOperations(dependentObject.getValidations());
    }

    private void mergeContainAction(GspBizEntityObject dependentObject) {
        getBizActions().mergeDbeOperations(dependentObject.getBizActions());
    }

    private void mergeChildObjects(GspBizEntityObject dependentObject, boolean isInit) {
        GspObjectCollection dbeChildObjects = dependentObject.getContainChildObjects().clone(this);
        GspObjectCollection childObjects = getContainChildObjects().clone(this);

        getContainChildObjects().clear();
        // 已有子对象
        if (childObjects != null && childObjects.size() > 0) {
            for (IGspCommonObject childObj : childObjects) {
                GspBizEntityObject childObject = (GspBizEntityObject) childObj;
                if (childObject.getIsRef()) {
                    for (IGspCommonObject dbeChildObj : dbeChildObjects) {
                        if (dbeChildObj.getID().equals(childObject.getID())) {
                            GspBizEntityObject dbeChildObject = (GspBizEntityObject) dbeChildObj;
                            childObject.mergeWithDependentObject(dbeChildObject, isInit);
                            getContainChildObjects().add(childObject);
                            dbeChildObjects.removeItem(dbeChildObject);
                        } else {
                            //// todo:若本来是dbe带过来的子对象，但是现在dbo上没有该对象了，则直接删掉；后续是否改为判断是否有非带出的字段/操作，有则保留为非带出子对象？
                            continue;
                        }
                    }
                } else {
                    getContainChildObjects().add(childObject);
                }
            }
        }

        // 若dbe中包含未对应到当前be的子对象，则新增
        if (dbeChildObjects == null || dbeChildObjects.size() < 1) {
            return;
        }
        for (IGspCommonObject item : dbeChildObjects) {
            GspBizEntityObject tempVar = new GspBizEntityObject();
            tempVar.setID(item.getID());
            tempVar.setIsRef(true);
            GspBizEntityObject newObj = tempVar;
            newObj.mergeWithDependentObject((GspBizEntityObject) ((item instanceof GspBizEntityObject) ? item : null), true); // 首次添加，故isInit为true,带出对象编号名称
            getContainChildObjects().add(newObj);
        }
    }

    // endregion

    public final void initMainObject() {
        setObjectType(GspCommonObjectType.MainObject);
        getBizActions().add(new DeleteBEAction());
        getBizActions().add(new ModifyBEAction());
        getBizActions().add(new RetrieveBEAction());
    }

    // region 创建BE子节点

    /**
     * 根据BE父节点生成子节点
     *
     * @param childObjCode BE子节点编号
     * @param childObjName BE子节点名称
     */
    public final GspBizEntityObject createChildObject(String childObjCode, String childObjName) {
        if (childObjCode.isEmpty()) {
            childObjCode = "childObj";
        }
        if (childObjName.isEmpty()) {
            childObjName = "childObj";
        }
        GspBizEntityObject childObj = initNewBizObject(childObjCode, childObjName);

        // 新增父节点id字段
        GspBizEntityElement parentIDElement = initParentIDElement();
        childObj.getContainElements().add(parentIDElement);

        // 子节点新增与父节点的关联
        GspAssociationKey key = new GspAssociationKey();
        GspBizEntityElement parentIdElement = initParentObjectIDElement();
        key.setTargetElement(parentIdElement.getID());
        key.setTargetElementDisplay(parentIdElement.getName());
        key.setSourceElement(parentIDElement.getID());
        key.setSourceElementDisplay(parentIDElement.getName());
        childObj.getKeys().add(key);
        return childObj;
    }

    private GspBizEntityObject initNewBizObject(String childObjCode, String childObjName) {
        GspBizEntityObject childObj = new GspBizEntityObject();
        GspBizEntityElement idElement = initIDElement();
        childObj.setID(Guid.newGuid().toString());
        childObj.setCode(childObjCode);
        childObj.setName(childObjName);
        GspColumnGenerate newColumnGenerate = new GspColumnGenerate();
        newColumnGenerate.setElementID(idElement.getID());
        newColumnGenerate.setGenerateType("Guid");
        childObj.setColumnGenerateID(newColumnGenerate);
        childObj.getContainElements().add(idElement);
        childObj.setObjectType(GspCommonObjectType.ChildObject);
        return childObj;
    }

    private GspBizEntityElement initIDElement() {
        GspBizEntityElement idElement = new GspBizEntityElement();
        idElement.setID(Guid.newGuid().toString());
        idElement.setCode("ID");
        idElement.setName("ID");
        idElement.setLabelID("ID");
        idElement.setMDataType(GspElementDataType.String);
        idElement.setObjectType(GspElementObjectType.None);
        idElement.setLength(36);
        idElement.setPrecision(0);
        idElement.setIsRequire(true);
        return idElement;
    }

    private GspBizEntityElement initParentObjectIDElement() {
        if (this.getColumnGenerateID() == null || this.getColumnGenerateID().getElementID().isEmpty()) {
            throw BusinessEntityException.createException(BusinessEntityErrorCodeEnum.GSP_BEMODEL_BUSINESS_ENTITY_0079);
        }
        Object tempVar = this.getContainElements().getItem(this.getColumnGenerateID().getElementID());
        return (GspBizEntityElement) ((tempVar instanceof GspBizEntityElement) ? tempVar : null);
    }

    private GspBizEntityElement initParentIDElement() {
        GspBizEntityElement idElement = new GspBizEntityElement();
        idElement.setID(Guid.newGuid().toString());
        idElement.setCode("ParentID");
        idElement.setName("ParentID");
        idElement.setLabelID("ParentID");
        idElement.setMDataType(GspElementDataType.String);
        idElement.setObjectType(GspElementObjectType.None);
        idElement.setLength(36);
        idElement.setPrecision(0);
        idElement.setIsRequire(true);
        return idElement;
    }

    public BizActionCollection getCustomBEActions() {
        BizActionCollection mgrActions = new BizActionCollection();
        mgrActions.setOwner(this);
        for (BizOperation operation : getBizActions()) {
            if (operation instanceof IInternalBEAction)
                continue;
            mgrActions.add((BizAction) operation);
        }
        return mgrActions;
    }

    // endregion

    // endregion
}
